# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-04 23:42
# File     : config.py
# Project  : codebuddy_craft
# Desc     : 配置管理
# backend/utils/config.py

# backend/utils/config.py
from pydantic_settings import BaseSettings
from pydantic import validator
from typing import Optional, List, Dict, Any
import os
from pathlib import Path


class Settings(BaseSettings):
    """应用配置设置 🛠️"""

    # ==================== 应用基础配置 ====================
    PROJECT_NAME: str = "CodeBuddy Craft"
    VERSION: str = "1.0.0"
    DESCRIPTION: str = "🚀 智能代码生成与协作平台"
    DEBUG: bool = False
    ENVIRONMENT: str = "development"  # development, production, testing
    API_V1_STR: str = "/api/v1"

    # 服务器配置
    HOST: str = "0.0.0.0"
    PORT: int = 8000
    WORKERS: int = 1

    # ==================== 数据库配置 ====================
    # 完整数据库URL（优先使用）
    DATABASE_URL: Optional[str] = None

    # 分离的数据库配置项
    DB_TYPE: str = "sqlite"  # postgresql, mysql, sqlite
    DB_HOST: str = "localhost"
    DB_PORT: int = 5432
    DB_USER: str = "postgres"
    DB_PASSWORD: str = "password"
    DB_NAME: str = "codebuddy.db"

    # 数据库连接池配置
    DB_POOL_SIZE: int = 5
    DB_MAX_OVERFLOW: int = 10
    DB_POOL_TIMEOUT: int = 30
    DB_POOL_RECYCLE: int = 3600
    DB_ECHO: bool = False  # 是否打印SQL语句

    @validator('DATABASE_URL', pre=True)
    def build_database_url(cls, v: Optional[str], values: Dict[str, Any]) -> str:
        """构建数据库URL"""
        if isinstance(v, str) and v:
            return v

        db_type = values.get('DB_TYPE', 'sqlite')
        if db_type.lower() == 'postgresql':
            return f"postgresql+asyncpg://{values.get('DB_USER')}:{values.get('DB_PASSWORD')}@{values.get('DB_HOST')}:{values.get('DB_PORT')}/{values.get('DB_NAME')}"
        elif db_type.lower() == 'mysql':
            return f"mysql+aiomysql://{values.get('DB_USER')}:{values.get('DB_PASSWORD')}@{values.get('DB_HOST')}:{values.get('DB_PORT')}/{values.get('DB_NAME')}"
        elif db_type.lower() == 'sqlite':
            db_path = Path(values.get('DB_NAME', 'codebuddy.db'))
            if not db_path.is_absolute():
                db_path = Path.cwd() / "data" / db_path
            db_path.parent.mkdir(parents=True, exist_ok=True)
            return f"sqlite+aiosqlite:///{db_path}"
        else:
            raise ValueError(f"不支持的数据库类型: {db_type}")

    # ==================== JWT认证配置 ====================
    SECRET_KEY: str = "your-super-secret-key-change-this-in-production"
    ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    REFRESH_TOKEN_EXPIRE_DAYS: int = 7

    @validator('SECRET_KEY')
    def validate_secret_key(cls, v):
        if len(v) < 32:
            raise ValueError('SECRET_KEY 长度至少为32个字符')
        return v

    # ==================== LLM配置 ====================
    # OpenAI配置
    OPENAI_API_KEY: Optional[str] = None
    OPENAI_MODEL: str = "gpt-3.5-turbo"
    OPENAI_MAX_TOKENS: int = 2000
    OPENAI_TEMPERATURE: float = 0.7
    OPENAI_BASE_URL: Optional[str] = None

    # Anthropic配置
    ANTHROPIC_API_KEY: Optional[str] = None
    ANTHROPIC_MODEL: str = "claude-3-sonnet-20240229"
    ANTHROPIC_MAX_TOKENS: int = 2000

    # 通用LLM配置
    DEFAULT_LLM_PROVIDER: str = "openai"  # openai, anthropic
    LLM_REQUEST_TIMEOUT: int = 60
    LLM_MAX_RETRIES: int = 3

    # ==================== 文件存储配置 ====================
    # 上传配置
    UPLOAD_DIR: str = "uploads"
    MAX_FILE_SIZE: int = 10 * 1024 * 1024  # 10MB
    ALLOWED_FILE_EXTENSIONS: List[str] = [
        '.py', '.js', '.ts', '.jsx', '.tsx', '.html', '.css', '.scss',
        '.rs', '.go', '.java', '.cpp', '.c', '.h', '.hpp',
        '.json', '.yaml', '.yml', '.toml', '.ini', '.cfg',
        '.md', '.txt', '.rst', '.sh', '.bat', '.ps1'
    ]

    # 项目存储
    PROJECTS_DIR: str = "projects"
    MAX_PROJECT_SIZE: int = 100 * 1024 * 1024  # 100MB
    upload_path: str = "uploads/projects"

    @validator('UPLOAD_DIR', 'PROJECTS_DIR')
    def create_directories(cls, v):
        path = Path(v)
        if not path.is_absolute():
            path = Path.cwd() / path
        path.mkdir(parents=True, exist_ok=True)
        return str(path)

    # ==================== Redis配置 ====================
    REDIS_URL: str = "redis://localhost:6379/0"
    REDIS_PASSWORD: Optional[str] = None
    REDIS_DB: int = 0
    REDIS_MAX_CONNECTIONS: int = 10
    REDIS_SOCKET_TIMEOUT: int = 5

    # 缓存配置
    CACHE_TTL: int = 3600  # 1小时
    SESSION_TTL: int = 86400  # 24小时

    # ==================== WebSocket配置 ====================
    # 连接限制
    WS_MAX_CONNECTIONS_PER_USER: int = 5
    WS_MAX_TOTAL_CONNECTIONS: int = 1000

    # 消息限制
    WS_MAX_MESSAGE_SIZE: int = 10 * 1024  # 10KB
    WS_MAX_MESSAGES_PER_MINUTE: int = 60

    # 心跳设置
    WS_PING_INTERVAL: int = 30  # 30秒
    WS_PING_TIMEOUT: int = 90  # 90秒

    # ==================== 日志配置 ====================
    LOG_LEVEL: str = "INFO"
    LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    LOG_FILE: Optional[str] = "logs/app.log"
    LOG_MAX_SIZE: int = 10 * 1024 * 1024  # 10MB
    LOG_BACKUP_COUNT: int = 5

    @validator('LOG_FILE', pre=True)
    def create_log_dir(cls, v):
        if v:
            log_path = Path(v)
            if not log_path.is_absolute():
                log_path = Path.cwd() / log_path
            log_path.parent.mkdir(parents=True, exist_ok=True)
            return str(log_path)
        return v

    # ==================== 安全配置 ====================
    # CORS配置
    CORS_ORIGINS: List[str] = ["http://localhost:3000", "http://localhost:8501"]
    CORS_ALLOW_CREDENTIALS: bool = True
    CORS_ALLOW_METHODS: List[str] = ["*"]
    CORS_ALLOW_HEADERS: List[str] = ["*"]

    # 速率限制
    RATE_LIMIT_REQUESTS: int = 100
    RATE_LIMIT_WINDOW: int = 60  # 60秒

    # 密码策略
    PASSWORD_MIN_LENGTH: int = 8
    PASSWORD_REQUIRE_UPPERCASE: bool = True
    PASSWORD_REQUIRE_LOWERCASE: bool = True
    PASSWORD_REQUIRE_DIGIT: bool = True
    PASSWORD_REQUIRE_SYMBOL: bool = False

    # ==================== 邮件配置 ====================
    SMTP_HOST: Optional[str] = None
    SMTP_PORT: int = 587
    SMTP_USER: Optional[str] = None
    SMTP_PASSWORD: Optional[str] = None
    SMTP_TLS: bool = True
    SMTP_SSL: bool = False

    EMAIL_FROM: Optional[str] = None
    EMAIL_FROM_NAME: str = "CodeBuddy Craft"

    # ==================== 监控配置 ====================
    # 健康检查
    HEALTH_CHECK_INTERVAL: int = 30  # 30秒
    HEALTH_CHECK_TIMEOUT: int = 5  # 5秒

    # 指标收集
    METRICS_ENABLED: bool = True
    METRICS_ENDPOINT: str = "/metrics"

    # ==================== 功能开关 ====================
    # 功能标志
    ENABLE_REGISTRATION: bool = True
    ENABLE_EMAIL_VERIFICATION: bool = False
    ENABLE_PASSWORD_RESET: bool = True
    ENABLE_USER_AVATARS: bool = True
    ENABLE_PROJECT_SHARING: bool = True
    ENABLE_REAL_TIME_COLLABORATION: bool = True
    ENABLE_CODE_EXECUTION: bool = True
    ENABLE_AI_SUGGESTIONS: bool = True

    # 实验性功能
    ENABLE_BETA_FEATURES: bool = False
    ENABLE_ADVANCED_ANALYTICS: bool = False

    # ==================== 开发配置 ====================
    # 调试选项
    DEBUG_SQL: bool = False
    DEBUG_REDIS: bool = False
    DEBUG_WEBSOCKET: bool = False

    # 测试配置
    TESTING: bool = False
    TEST_DATABASE_URL: Optional[str] = None

    # ==================== 性能配置 ====================
    # 并发配置
    MAX_WORKERS: int = 4
    WORKER_TIMEOUT: int = 30

    # 缓存配置
    ENABLE_QUERY_CACHE: bool = True
    ENABLE_TEMPLATE_CACHE: bool = True
    ENABLE_STATIC_CACHE: bool = True

    # ==================== 第三方服务配置 ====================
    # GitHub集成
    GITHUB_CLIENT_ID: Optional[str] = None
    GITHUB_CLIENT_SECRET: Optional[str] = None

    # Google集成
    GOOGLE_CLIENT_ID: Optional[str] = None
    GOOGLE_CLIENT_SECRET: Optional[str] = None

    # 对象存储（如AWS S3）
    AWS_ACCESS_KEY_ID: Optional[str] = None
    AWS_SECRET_ACCESS_KEY: Optional[str] = None
    AWS_REGION: str = "us-east-1"
    AWS_BUCKET_NAME: Optional[str] = None

    class Config:
        env_file = ".env"
        env_file_encoding = 'utf-8'
        case_sensitive = True

        # 环境变量前缀
        env_prefix = ""

        # 允许的字段
        fields = {
            'SECRET_KEY': {'env': ['SECRET_KEY', 'JWT_SECRET']},
            'DATABASE_URL': {'env': ['DATABASE_URL', 'DB_URL']},
            'REDIS_URL': {'env': ['REDIS_URL', 'CACHE_URL']},
        }

    def get_database_config(self) -> Dict[str, Any]:
        """获取数据库配置字典"""
        return {
            'url': self.DATABASE_URL,
            'pool_size': self.DB_POOL_SIZE,
            'max_overflow': self.DB_MAX_OVERFLOW,
            'pool_timeout': self.DB_POOL_TIMEOUT,
            'pool_recycle': self.DB_POOL_RECYCLE,
            'echo': self.DEBUG or self.DEBUG_SQL
        }

    def get_llm_config(self, provider: Optional[str] = None) -> Dict[str, Any]:
        """获取LLM配置"""
        provider = provider or self.DEFAULT_LLM_PROVIDER

        if provider == "openai":
            return {
                'api_key': self.OPENAI_API_KEY,
                'model': self.OPENAI_MODEL,
                'max_tokens': self.OPENAI_MAX_TOKENS,
                'temperature': self.OPENAI_TEMPERATURE,
                'base_url': self.OPENAI_BASE_URL,
                'timeout': self.LLM_REQUEST_TIMEOUT,
                'max_retries': self.LLM_MAX_RETRIES
            }
        elif provider == "anthropic":
            return {
                'api_key': self.ANTHROPIC_API_KEY,
                'model': self.ANTHROPIC_MODEL,
                'max_tokens': self.ANTHROPIC_MAX_TOKENS,
                'timeout': self.LLM_REQUEST_TIMEOUT,
                'max_retries': self.LLM_MAX_RETRIES
            }
        else:
            raise ValueError(f"不支持的LLM提供商: {provider}")

    def get_cors_config(self) -> Dict[str, Any]:
        """获取CORS配置"""
        return {
            'allow_origins': self.CORS_ORIGINS,
            'allow_credentials': self.CORS_ALLOW_CREDENTIALS,
            'allow_methods': self.CORS_ALLOW_METHODS,
            'allow_headers': self.CORS_ALLOW_HEADERS
        }

    def is_production(self) -> bool:
        """判断是否为生产环境"""
        return self.ENVIRONMENT.lower() == "production"

    def is_development(self) -> bool:
        """判断是否为开发环境"""
        return self.ENVIRONMENT.lower() == "development"

    def is_testing(self) -> bool:
        """判断是否为测试环境"""
        return self.TESTING or self.ENVIRONMENT.lower() == "testing"


# 创建全局设置实例
settings = Settings()


# 环境特定配置
class DevelopmentSettings(Settings):
    """开发环境配置"""
    DEBUG: bool = True
    LOG_LEVEL: str = "DEBUG"
    DEBUG_SQL: bool = True
    ENABLE_BETA_FEATURES: bool = True
    upload_path: str = "uploads/projects"


class ProductionSettings(Settings):
    """生产环境配置"""
    DEBUG: bool = False
    LOG_LEVEL: str = "INFO"
    DEBUG_SQL: bool = False
    ENABLE_BETA_FEATURES: bool = False
    upload_path: str = "/var/uploads/projects"

    # 生产环境安全检查
    @validator('SECRET_KEY')
    def validate_production_secret_key(cls, v):
        if v == "your-super-secret-key-change-this-in-production":
            raise ValueError('生产环境必须设置安全的SECRET_KEY')
        return v


class TestingSettings(Settings):
    """测试环境配置"""
    TESTING: bool = True
    DATABASE_URL: str = "sqlite+aiosqlite:///test.db"
    REDIS_URL: str = "redis://localhost:6379/15"  # 使用测试数据库
    LOG_LEVEL: str = "WARNING"
    upload_path: str = "test_uploads/projects"


def get_settings() -> Settings:
    """根据环境获取对应的配置"""
    env = os.getenv("ENVIRONMENT", "development").lower()

    if env == "production":
        return ProductionSettings()
    elif env == "testing":
        return TestingSettings()
    else:
        return DevelopmentSettings()

# 如果需要根据环境自动选择配置，可以使用：
# settings = get_settings()
